//
//  ASIQWHttpEngine.m
//  117goFramework
//
//  Created by Yunhai.Wu on 15/7/30.
//  Copyright (c) 2015年 117go. All rights reserved.
//

#import "ASIQWHttpEngine.h"
#import "ASIHttpRequest.h"
#import "ASIFormDataRequest.h"
#import "QWNetworkActivityService.h"
#import "QWHttpUtil.h"

@implementation ASIQWHttpEngine

-(ASIHTTPRequest*) asiHttpRequest:(id<IQWHttpRequest>) request {
    NSString *url = [request getURL];
    NSString *method = [[request getMethod] uppercaseString];
    NSDictionary *params = [request getParams];
    NSDictionary *headers = [request getHeaders];
    long timeoutDuration = [request getTimeoutDuration] <= 0 ? 60 : [request getTimeoutDuration];
    ASIHTTPRequest *asiHttpRequest = nil;
    NSMutableString *reqURL = [[NSMutableString alloc] initWithString:url];
    if ([method isEqualToString:HTTP_METHOD_GET]) {
        if ([params count] > 0) {
            [reqURL appendFormat:@"?%@",[QWHttpUtil stringWithFormEncodedComponents:params]];
        }
        asiHttpRequest = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:reqURL]];
        QWLogDebug(@"HTTP GET url:%@",reqURL);
    } else {
        QWLogDebug(@"HTTP %@ url:%@",method,url);
        QWLogDebug(@"HTTP Params:%@",params);
        if ([request existUploadFile]) {
            NSDictionary *uploadFiles = [request getUploadFiles];
            ASIFormDataRequest *asiFormDataRequest = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:reqURL]];
            NSArray *allKeys = [uploadFiles allKeys];
            for (NSString *key in allKeys) {
                NSString *filePath = [uploadFiles objectForKey:key];
                NSString *fileName = [filePath lastPathComponent];
                [asiFormDataRequest addFile:filePath withFileName:fileName andContentType:@"application/octet-stream" forKey:key];
            }
            NSData *postValue = [request getBodyData];
            if (postValue == nil && [params count] > 0) {
                NSError *error;
                id data = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&error];
                postValue = [[NSMutableData alloc] initWithData:data];
            }
            if ([postValue length] > 0) {
                [asiFormDataRequest setData:postValue withFileName:nil andContentType:@"application/json; encoding=utf-8;" forKey:@"data"];
            }
            asiHttpRequest = asiFormDataRequest;
        } else {
            asiHttpRequest = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:reqURL]];
            NSData *postBody = [request getBodyData];
            if (postBody == nil && [params count] > 0) {
                NSError *error;
                id data = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&error];
                postBody = [[NSMutableData alloc] initWithData:data];
            }
            [asiHttpRequest setPostBody:[[NSMutableData alloc] initWithData:postBody]];
        }
    }
    [asiHttpRequest setRequestMethod:method];
    if ([headers count] > 0) {
        QWLogDebug(@"HTTP Headers:%@",headers);
        NSArray *keys = [headers allKeys];
        for (NSString *key in keys) {
            if ([[headers objectForKey:key] isKindOfClass:[NSString class]]) {
                [asiHttpRequest addRequestHeader:key value:[headers objectForKey:key]];
            }
        }
    }
    QWLogDebug(@"HTTP TimeOutSeconds:%li",timeoutDuration);
    [asiHttpRequest setTimeOutSeconds:timeoutDuration];
    return asiHttpRequest;
}

-(void)asynRequest:(id<IQWHttpRequest>)request responseClass:(Class)resClass responseBlock:(WJHttpEngineResponseBlock)resBlock {
    QWLogDebug(@"HTTP Asyn Request");
    if (request && resClass != Nil && [resClass conformsToProtocol:@protocol(IQWHttpResponse)] && [request validateParams] && ![self hasLoading]) {
        QWLogDebug(@"HTTP validateParams SUCCESS");
        self.resBlock = resBlock;
        ASIHTTPRequest *asiHttpRequest = [self asiHttpRequest:request];
        if (self.showNetworkActivityIndicator) {
            [[QWNetworkActivityService sharedInstance] start];
        }
        __unsafe_unretained ASIQWHttpEngine *selfObjectRef = self;
        __unsafe_unretained ASIHTTPRequest *requestObjectRef = asiHttpRequest;
        [asiHttpRequest setCompletionBlock:^{
            if (selfObjectRef.showNetworkActivityIndicator) {
                [[QWNetworkActivityService sharedInstance] stop];
            }
            selfObjectRef.loading = NO;
            id<IQWHttpResponse> response = [resClass parseResult:[requestObjectRef responseData]];
            [[QWHttpFilterCore sharedInstance] filter:response];
            QWLogDebug(@"HTTP Response SUCCESS~");
            if (selfObjectRef.resBlock != NULL) {
                selfObjectRef.resBlock(response,nil);
                selfObjectRef.resBlock = NULL;
            }
        }];
        [asiHttpRequest setFailedBlock:^{
            if (selfObjectRef.showNetworkActivityIndicator) {
                [[QWNetworkActivityService sharedInstance] stop];
            }
            QWLogDebug(@"HTTP Response Error:%@",[requestObjectRef error]);
            selfObjectRef.loading = NO;
            if (selfObjectRef.resBlock != NULL) {
                selfObjectRef.resBlock(nil,[requestObjectRef error]);
                selfObjectRef.resBlock = NULL;
            }
        }];
        self.loading = YES;
        [asiHttpRequest startAsynchronous];
    } else {
        QWLogError(@"HTTP validateParams Fail");
        if (resBlock != NULL) {
            NSError *error = [NSError errorWithDomain:@"ASIWJHttpEngineDomain" code:-1 userInfo:[NSDictionary dictionaryWithObject:@"不符合请求条件" forKey:NSLocalizedDescriptionKey]];
            resBlock(nil, error);
        }
    }
}

-(id<IQWHttpResponse>)syncRequest:(id<IQWHttpRequest>)request responseClass:(Class)resClass error:(NSError *__autoreleasing *)error {
    QWLogDebug(@"HTTP Sync Request");
    __block id<IQWHttpResponse> response = nil;
    if (request && resClass != Nil && [resClass conformsToProtocol:@protocol(IQWHttpResponse)] && [request validateParams]) {
        QWLogDebug(@"HTTP validateParams SUCCESS");
        ASIHTTPRequest *asiHttpRequest = [self asiHttpRequest:request];
        if (self.showNetworkActivityIndicator) {
            [[QWNetworkActivityService sharedInstance] start];
        }
        __unsafe_unretained ASIQWHttpEngine *selfObjectRef = self;
        __unsafe_unretained ASIHTTPRequest *requestObjectRef = asiHttpRequest;
        [asiHttpRequest setCompletionBlock:^{
            if (selfObjectRef.showNetworkActivityIndicator) {
                [[QWNetworkActivityService sharedInstance] stop];
            }
            selfObjectRef.loading = NO;
            QWLogDebug(@"HTTP Response SUCCESS~");
            response = [resClass parseResult:[requestObjectRef responseData]];
        }];
        [asiHttpRequest setFailedBlock:^{
            if (selfObjectRef.showNetworkActivityIndicator) {
                [[QWNetworkActivityService sharedInstance] stop];
            }
            selfObjectRef.loading = NO;
            *error = [requestObjectRef error];
            QWLogDebug(@"HTTP Response Error:%@",[requestObjectRef error]);
        }];
        self.loading = YES;
        [asiHttpRequest startSynchronous];
    } else {
        QWLogError(@"HTTP validateParams Fail");
        *error = [[NSError alloc] initWithDomain:@"ASIWJHttpEngineDomain" code:11 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"参数错误",@"errorCode", nil]];
    }
    [[QWHttpFilterCore sharedInstance] filter:response];
    return response;
}

@end
